用 python 进行信号的重建

信号重建的目的是将采样率小的信号用更高的采样率进行插值得到更加逼近真实情况的信号,根据采样定理可知,采样后的频谱是原信号频谱的多次重复,我们将高频的部分滤去就是真正的频谱,所以将需要重建的信号通过一个低通滤波器就可以实现信号重建,也就是将信号与采样率更高的 sinc 函数进行卷积。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import numpy as np
import matplotlib.pyplot as plt

for n in [1, 2, 4]: # 对三种情况进行遍历
fm = 5 # 最大频率
fs = n * fm # 采样频率
ts = 1 / fs # 采样间隔
Ts = 4 # 采样总时间
N = int(Ts / ts) # 采样点数

t = np.linspace(-2, 2, N) # 采样的横坐标
ft = np.sin(2 * np.pi * t) + (1 / 3) * np.sin(6 * np.pi * t) # 采样的函数值

# 下面对信号进行 fft
freqx = np.fft.fftfreq(N, d=1 / fs)
fft_vals = np.fft.fft(ft)
fft_theo = 2.0 * np.abs(fft_vals / N)

# 开始重建信号
over_times = 10 # 过采样率为 10 倍,即重建后的采样密度是重建前的 10 倍
fs_r = over_times * fs # 重建后的采样频率
Ts_r = Ts # 重建后的采样总时间不变
N_r = int(Ts * fs_r) # 重建后的采样点数
ts_r = 1 / fs_r # 重建后的采样间隔
t_r = np.linspace(-2, 2, N_r) # 重建后的横坐标
ft_r = np.zeros(N_r) # 先将存放重建后的函数值的容器初始化为零

# 将原信号与理想低通滤波器的脉冲响应(即sinc函数)进行卷积
for point_r in range(N_r):
for point in range(N):
ft_r[point_r] += ft[point] * np.sinc((point_r*ts_r - point*ts)/ts)

# 画图
plt.figure() # 建立总图
index = 1 # 子图序号初始值

# 画出采样信号图像
plt.subplot(3, 1, index)
a = plt.stem(t, ft, '-')
plt.title('signal of %sfm' % n)
plt.setp(a, color='b')
plt.xlabel('time(s)')
index += 1 # 子图索引值加 1

# 画出采样信号的频谱图
plt.subplot(3, 1, index)
b = plt.stem(freqx, fft_theo, '-')
plt.title('spectrum of signal of %sfm' % n)
plt.setp(b, color='r')
plt.xlabel('frequency(Hz)')
index += 1

# 画出重建后的信号
plt.subplot(3, 1, index)
a = plt.plot(t_r, ft_r, '-') # 画图
plt.title('reconstructed signal of %sfm' % n)
plt.setp(a, color='b')
plt.xlabel('time(s)')

# 调整布局
plt.tight_layout()
plt.subplots_adjust(wspace=0.4, hspace=0.4)

plt.show() # 显示图像

参考文章:

微信捐赠
支付宝捐赠